package com.cn.wanxi.util;

import com.cn.wanxi.model.ResultModel;
import com.cn.wanxi.model.UserModel;

import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class ReadMe {
    /**
     * 2022-4-6
     * 第四阶段：任务需求：写一个完整的后台管理系统，
     * 后台技术：mysql+servlet
     * 前端技术：html+css+js+jq,ajax,layui,xadmin,vue,axure
     * -----------------------------------
     * 数据库mysql
     * 1.安装mysql，注意：要安装包，不要下载压缩包
     * 2.用户名和密码一般写root和123456
     * 3.如果安装失败，有可能需要下载vs
     * 4.安装服务的时候有可能失败  service ，那么需要卸载mysql重新安装
     * 注意：卸载mysql时，需要彻底删除注册表，然后重启电脑
     * -----------------------------------------------------------
     * 连接数据
     * 下载安装 可视化工具
     * 1.hostname 地址
     * 2.port  端口  默认3306
     * 3.username   root
     * 4.password   123456
     * 5.connection name   ：连接名称，随便取，一般取项目名
     * ------------------------------------------------------------
     * 新建数据库：
     * 1.定义？mysql是什么？
     * 2.优势？为什么用？
     * 3.应用场景？哪些地方需要用？
     * 4.怎么用？
     *----------------------------------------------------
     * 先用，然后再思考什么意思
     * 华为学的是ibm
     * 先僵化，再固化，再优化
     * ---------------------------------------------------
     * 创建数据库：
     * CREATE DATABASE canyin;
     * CREATE SCHEMA `canyin2` ;
     * 删除数据库
     * DROP DATABASE `canyin2`;
     * 数据库里面包含哪些内容？
     * 1.tables   表
     * 2.views   视图
     * 3.Stored Procedures 存储过程
     * 4.functions 函数，方法
     * 为什么不适用存储过程？
     * -------------------------------------
     * 建表是什么意思？为什么要建表？表内容可以做什么？
     * 1.数据库主要作用就是保存数据
     * 2.如果用mysql和第二阶段怎么保存第二阶段的数据
     * 数据库     dao 层                canyin （MySQL数据库名）
     *           类名CompanyDao           表名
     *           属性                     列名
     *           属性数据类型             数据类型
     *  创建数据库表的时候，
     *
     *
     *
     *
     */
    /**
     * 2022-4-7
     * 数据库命名规范：应该是全部小写：如果由两个单词，则用下划线 company_logo
     * 数据库不区分大小写
     * 面试：数据库引擎InnoDB和MyISAM的区别?
     * 在第四阶段创建表的时候，我们第二阶段所有属性都应该对于数据库的列
     * 在这里要注意：我们创建表的时候，需要注意哪些内容？哪些关键？
     * 1.对象不可再分，一直拆分到最小为止
     * 2.唯一性：是指里面的每一天内容不能相同，我写了一个主键（主键在表里面不能一样）
     *  主键是自动自增（自动增长）主键自带索引，查询效率比较高
     * 3.冗余性 表与表之间最好没有任何关联
     * ----------------------------------------
     * pk 主键
     * NN 不为空
     * UQ 唯一性
     * AI 自动增长 一般用于主键
     * ---------------------------------------
     * 一般情况下，每个班都应该有的列
     * 1.id 主键
     * 2.create_time 创建时间
     * 3.update_time 更新时间
     * 4.remark       备注  最近更新密码的时间，或者登录QQ的时间，你最近用过的密码
     * 5.enable    状态是否使用，1.正在使用，2.停用，3.注销，4.在线 5.被踢出
     * -------------------------------
     * id应该用什么数据类型？
     * tinyint     byte   1
     * smallint     short  2
     * int    int  4
     * bigint   long  8
     * id多大合适根据数据的量有关；
     * 如果当前的数据最多一百条，那么我们就不要用int  直接用什么？为什么？tinyint
     * 为什么不直接用int，都可以啊？浪费资源
     * Java求平均值？假如给两个数求平均值？  (a+b)/2
     * 作为扩展：
     * 1.假如a和b为整型的最大值？还可以用(a+b)/2吗？内存溢出
     * 2.内存编码：32位？64位？
     *      a/2 +b/2+a^b^1
     * ----------------------------------------------
     * 面试的时候：可不可以用bigint？你们以前的项目有咩有用bigint？
     * 1.考虑数据的量大小（条数）
     * 2.考虑bigint的大小
     * 3.考虑数据的长度（每一条数据的长度）
     * ---------------------------------------------------------------
     * 一般情况下不要用bigint，就是说Java的model里面id的数据类型不要有Long？
     * 因为一般情况下：数据库里面的数据大于500万条或者大小在2G以上都要考虑分库分表
     * 如果你做一个微信聊天：对于微信聊天记录的数据应该怎么存储？
     * 回答问题之前：你要反问面试官：
     * 1）请问数据类一天大概是都少？
     * 2）用户量大概有多少？
     * 3）使用频率大概是多少？
     * -----------------------------------------------
     * 1.根据群人数多少进行建表
     * 2.根据群地域进行建表   成都，北京，上海，
     * 3.根据时间来进行建表
     * 4.根据群内容条数进行建表
     * 5.根据群内容的大小进行建表
     * --------------------------------------------------
     * 数据库永远不要存文件：不要把图片，文件存于数据库，因为很耗资源
     * 那么数据库直接存文件的地址即可
     * 对于字符串我们数据库应该用什么数据类型？
     * 1）请问你的文件地址一般存放在哪里？
     * 2）请问你的文件地址一般有多长？
     * 3）请问你的文件地址是否经常查询？
     * -----------------------------------------
     * 数据库可以存放字符串的数据类型：varchar  char  text
     * char 一般用于字节255之内；80个字符 长度不变
     * varchar   一般用于可变字符
     * text  一般用于存文本
     * -----------------------
     * TIMESTAMP()和DATETIME的区别？优势？
     * 建议用DATETIME
     * TIMESTAMP区间  1970：0：0 0：0：0 到2038：0：0：0
     * DATETIME    0：0：0：0    9999：12：31 24：59：59
     * TIMESTAMP带时区  这个很多时候容易出错，很多时间无法表达
     *DATETIME不带时区
     * TIMESTAMP 字节数 4个字节
     * DATETIME 8个字节
     * TIMESTAMP如果带毫秒好像是7个字节
     * 怎么来判断带毫秒呢？
     * DATETIME（6）表示带6个毫秒数  2022/4/7 15：15：15 555555
     * DATETIME 2022/4/7 15：15：15
     * date   2022/4/7
     * time 15：15：15
     * -------------------------------------------
     * 数据库没有Boolean值，直接用tinyint代替
     * 所以数据库数据类型有：
     * 1.char
     * 2.varchar
     * 3.text
     * 4.datetime
     * 5.int
     * 6.decimal(5,3); 5代表有效数字，3代表小数点后有三位:一般用于金钱
     * ----------------------------------------------------------------
     * `   ' ‘
     * `这个的含义就是：将我们自己写的包含起来，表示将这些当作普通字符，而不是关键字
     * create table   表名(列名，数据类型，默认值)
     * CREATE TABLE `canyin`.`company` (
     *   `id` INT NOT NULL,
     *   `logo` VARCHAR(100) NULL,
     *   `phone` CHAR(11) NULL,
     *   `net` VARCHAR(45) NULL,
     *   `email` VARCHAR(45) NULL,
     *   `address` VARCHAR(45) NULL,
     *   `line_phone` CHAR(13) NULL,
     *   `version` VARCHAR(45) NULL,
     *   `create_time` DATETIME(6) NULL,
     *   `update_time` DATETIME NULL,
     *   `enable` TINYINT(1) NULL,
     *   `remark` VARCHAR(45) NULL,
     *   `is_show` TINYINT NULL,
     *   PRIMARY KEY (`id`))
     * ENGINE = InnoDB;
     * 当我们创建表的时候，怎么选择数据库？
     * use canyin; 选择数据库
     * --------------------------------------------------
     * 今天的任务：
     * 1.将所有的对象建表
     * 2.建表的时候要多几个固定的列
     * 3.将数据库多的这几列 全部在model层里面去实现
     * model应该和数据库的列一一对应
     * --------------------
     * 今天讲的知识点：
     * 1.数据类型
     * 2.数据库命名规范
     * 3.表创建注意事项
     * 4.三大范式
     * ---------------------------------------
     * 明天内容：
     * 1.数据定义语言：修改
     * 2.数据操纵语言：增删改
     * 3.数据控制语言：权限设计
     *
     *
     *
     */
    /**
     * 2022-4-8
     * 修改  表    数据库.表名
     * 删除  列    列名；
     * ALTER TABLE `canyin`.`company`
     * DROP COLUMN `is_show`;
     * 修改  列   以前的列   现在的列  数据类型
     * CHANGE COLUMN `version` `company_version` VARCHAR(200) NULL DEFAULT '' ;
     * -- 向查询出当前数据库又多少张表
     * show tables;
     * 如果数据库里面的数据在公司，那么回到家以后，数据怎么同步呢？
     * 1. 你可以去买一个云数据库（远程数据库）
     * 2.你可以去买一个云服务器（就是一台电脑）
     * 3.你可以将当前数据库的数据拷贝出来，然后回到家导入到你家里的电脑上
     *  1)删除当前表：删除之前判断当前表是否存在，DROP TABLE IF EXISTS `company`;
     *  2）创建表
     *  3）将当前表锁住，目的是为了只能一个人去修改
     *  4）将所有数据新增到数据库
     *  5）释放当前锁
     * -----------------------------------------------------------
     * 导出：
     * 1.点击administration 选择 data export
     * 2.选择我们需要导出数据的数据库
     * 3.选择export to self-contained file ，找到你想将数据存入的那个文件
     * 4.选择export progress，点击最右下角的start exprot
     * ---------------------------------------------------
     * 导入数据：
     * 1.点击administration ，选择data import/restore
     * 2.选择Import from self-contained file,去找到刚刚的sql文件
     * 3.选择一个数据库，或者重新创建一个数据库
     * 4.选择import progress 点击右下角的start import
     * ---------------------------------------------------------------
     * 有没有可能你现在的数据库给其他同事用？
     * 这时并不是同事直接用你的用户名密码和ip地址直接可以访问，我们要给他一个权限
     * 分配权限的步骤：
     * 1.点击administration ，选择users  and privileges
     * 2.点击添加账号：add account
     * 3.配置用户名
     * 4.配置有访问权限的地址%表示所有人都可以访问：
     *      1）192.168.41._表示只能是192.168.41.0 到192.168.41.9
     *      2）192.168.41.1_2  表示192.168.41.102到192.168.41.192
     *      3）192.168.41.__1
     *      4)192.168._1.___
     * 5.点击右下角apply就可以使用了。
     * ------------------------------
     * 这里只是代表用户可以访问，但没有任何其他权限，还没有给用户分配权限
     * 6.选择schema privileges ，进行权限分配
     * 7.选择你想分配给他的数据库，点击ok
     * 8.选择具体的权限进行配置：
     * ------------------------------------------------------------------------
     * 数据操纵语言：就算对表数据的新增，修改，删除
     * INSERT INTO `company` (`logo`, `phone`, `net`, `email`, `address`,
     *  `line_phone`, `company_version`,
     *  `create_time`, `update_time`, `enable`, `remark`) VALUES
     *  ('../img/logo.jpg', '1399999999', 'www.wanxi.com', 'wanxi@wanxi.com', '孵化园',
     *  '028-999999', 'fasdfasdkfhaslkd',
     *  '2020-02-02', '2020-02-02', '1', 'fasd');
     *  新增数据：
     *  insert into 表名（列名，列名）values（值，值）
     *  注意：
     *  1.列名一一对应
     *  2.数据格式正确
     *  3.主键自增
     * ---------------------------------------------
     * 面试：怎么得到mysql的系统时间？ now(),sysdate()
     * 怎么拿到毫秒数？
     * 这里可能用Java代码来拿，用mysql很复杂
     *  select UNIX_TIMESTAMP(create_time)*1000 from company;
     * 扩展：java 日期转换？
     * 打印出昨天的当前日期？今天是2020年3月1号
     * --------------------------------------------------------
     * ALTER TABLE `canyin`.`table`
     * ADD COLUMN `update_time` DATETIME NULL DEFAULT now();
     * 将当前的修改时间默认为系统时间：注意，时间不要有毫秒DATETIME(6)
     * -------------------------------------------------------------
     *  UPDATE `company` SET
     *  `logo` = 'a', `phone` = 'a', `net` = 'a',
     *  `email` = 'a', `address` = 'a', `line_phone` = 'a',
     *  `company_version` = 'a',
     *  `update_time` = now(), `enable` = '0', `remark` = 'a'
     *  WHERE (`id` = '4');
     *  修改表数据格式：
     *  update  表名  set
     *  列名='值'，
     *  列名='值'
     *  where  id=4;
     *  ------------------------------------------------------------------
     *  DELETE FROM `canyin`.`company` WHERE (`id` = '3');
     *  删除数据格式：
     *  delete from  表名  where  id=3
     *  --------------------------------------------------------
     *  以后我们的数据库没有删除，没有物理删除，只有逻辑删除
     *  如果我想让某一天不显示，让用户感觉已经删除，我们应该用修改
     *  1表示启用，0表示停用
     *  update company set enable=0 where id=2;
     *  --------------------------------
     *  面试的时候：
     *  delete  感觉已经删除，但是可以去缓存里面去找回来。类似于回收站
     *          一般用于删除一条数据   表还在，内容也还在，只是看不见，可以找回
     *  truncate 彻底删除，找不回来  类似于  我们用快捷键删除文件  shift+delete
     *              truncate 一般用于清空整个表数据  表还在，内容不在了
     *  drop   直接删除表  删除表结构  所有的东西都不在了
     *  之间的区别？
     *-------------------------------------------------------------------
     * 今天知识点：
     * 1.数据定义语言
     * 2.数据的导入导出
     * 3.数据的权限分配
     * 4.数据的操纵语言（新增，修改，删除）
     * ------------------------------------------------
     * 下节课知识点;
     * 1.运算符
     * 2.查询语言
     * 3.外链
     * 将你们页面上的数据通过sql语句插入到数据库
     * 练习新增，删除，修改的sql语句
     *
     */
    /**
     * 2022-4-11
     * 1.查询当前表内容
     * SELECT * FROM user;  查询所有数据,不能直接用，因为如果当前表又一亿条数据呢？
     * 2.我们需要对当前表做一个条件语句  默认情况下 我们会查询出前一千条数据
     * SELECT * FROM user limit 1000;完整版查询前一千条数据
     * 注意：以后都不能查询所有而不带条件
     *
     * 3.怎么带条件？where 条件语句
     * select * from user where id=4;//根据id=4查询当前sql语句
     * 查询单条数据，因为id唯一
     * 4.SELECT * FROM product
     * where (normal_price+price)>500;
     *      1）查询正常价和市场价的和大于500；
     *      2）如果某一列中有不属于数字的，则不能进行相加，则会忽略
     *      3）我们价格设置为数字时，默认值不能为空或者null或者字符串
     * 5.如果将(normal_price+price)>500放到select 和from之间，表示查询出是否的结果，布尔值
     * 要么出现1，要么出现0，为空的时候表示不能进行运算
     * select (normal_price+price)>500 from product;//查询结果有3个数，null，1，0
     * 将这个结果当作一个临时表，然后对里面的数据进行分组，分组的目的就是将相同的查询出来，保留一个
     * select * from (
     * select (normal_price+price)>500 as price from product )as aa  group by price;
     * -----------------------------------------------------------------------
     * 分组：SELECT is_show FROM product group by is_show;
     * 1.分组的时候，group by后面的列名 必须和select 和from之间的列名一直（最好一直）
     * 2.如果想要和几个列一起分组，则在后面加即可
     * -------------------------------------------------------------
     * 6.select * from product where id>5 and id<15; -- 逻辑与，同时满足条件
     * 7.select * from product where  id between 7 and 22; 在什么之间，等同于  id>=7 和id<=22
     * 8.select * from product where id in(7,22) 在括号里的都查询出来，
     * 9.select * from product where id  not in(7,22)  只要不是括号里的数据都查询出来
     * 注意：以后不要用not in ,因为会遍历整个数据库，加剧数据库查询负担
     * -------------------------------------------------------
     * 10.select * from product    order by id desc;
     * 排序，可以根据指定的列进行排序，desc叫做降序，asc升序，默认升序，所以可以不写asc
     * 11.模糊查询
     * SELECT * from product where name like 's%';
     * SELECT * from product where name like '%s';
     * SELECT * from product where name like '%s%';
     * SELECT * from product where name like '%回%' and name like '%肉%';
     * SELECT * from product where name like '%回%' or name like '%肉%';
     * ------------------------------
     * SELECT * from product where name like '__鹏';这种一般用于查姓名，**鹏
     * SELECT * from product where name like '__鹏%';
     * SELECT * from product where name like '%__鹏%';
     *
     * SELECT * from product where name REGEXP '[肉回]';中括号里面只要有一个正确即可
     * SELECT * from product where name REGEXP '[0-9]'; 只要name里面包含有一个数字即可
     * -------------------------------------------------------------------------------
     * 12.分页
     * 1)       limit分页公式
     * （1）limit分页公式：curPage是当前第几页；pageSize是一页多少条记录
     * limit (curPage-1)*pageSize,pageSize
     * -- curPage=3,pageSize=5;
     * select * from product limit (3-1)*5,5;//这个是错误的，不能是运算符，
     * select * from product limit 10,5;//是正确的，只能将结果写在这里
     * -- select * from product limit start,end;
     * 1）start从什么时候开始数end往后面数5条数据
     * 2）limit后面的start不能是一个运算符，只能是一个结果
     * 3)limit后面如果只有一个参数，表示从0开始，往后面数多少条。limit 100，取前面一百条数据
     * （2）用的地方：sql语句中
     * select * from student limit(curPage-1)*pageSize,pageSize;
     *（3）查询总条数：totalRecord是总记录数
     * SELECT COUNT(*) FROM product；42条
     * SELECT COUNT(is_show) FROM product；9条
     * 说明：is_show查询不出正确条数，是因为is_show里面有些值有空，会自动跳过
     * 所以，count(*)里面最好直接用*，它可以根据索引直接查询，速度最快，默认按索引查询
     * （4）查询总页数：
     * 思路：假如有42条，每一页显示10条，则一共有5页，最后一页2条
     * 总条数/每一页显示的条数=结果有可能是一个整数，有可能是一个小数，
     * 想要得到总页数：那么就将结果向上取整
     * ----------------------------------------------------------
     * 自我约束  自律
     * -------------------------------------------
     * 今日知识点：
     * 1.运算符
     * 2.分组，排序
     * 3.模糊查询
     * 4.分页
     * 预习内容：
     * 1.mysql函数
     * 2.mysql查询（联合查询）
     * 3.练习sql语句
     *
     *
     */
    /**
     * 2022-4-12
     * select id a,price b from product;
     * select min(price) price from product;
     * 最大值，最小值，不包括null或者空，
     * 就像Java的数据类型都有默认值一样。
     * Java里面所有的实体类（model），所有的数据类型不能是基本类型
     * 对于数据库里面查询出的数据，我们会用Java类取接收，
     * 如果数据库里面查询出是null的情况下，而Java你用的是整型（基本类型）来接收，会报错
     * ---------------------------------
     * 注意：我们数据库里面的数据不要有空值，格式一定要正确，
     * ------------------------------------
     * 数据类型转换：字符串转换为整型：Integer.parseInt();Integer.valueOf();
     * 求和，平均值  一般用于学生成绩，用户的年龄等等
     * select DATE_FORMAT(create_time,'%Y/%m-%d'), create_time from product;
     * mysql日期格式化
     * Java日期格式化
     * js日期格式化
     * ---------------------------------------------------------------------
     * 举例：在百度里面搜索Java时，会出现几条广告，加正常信息，加广告信息，加正常信息
     * 如果每增加一个状态，则在数据库表里面增加一列，是不明确，不明智的。
     * 所以，我们可以只增加一列：用状态码来表示
     * 1,置顶，2，热点，3表示推荐，4.普通，5其他
     * ALTER TABLE `canyin04`.`product`
     * ADD COLUMN `style` TINYINT NULL COMMENT '状态' AFTER `cuisine_id`;
     * 合并查询：就是将不同的数据进行合并
     * (select * from product where style=1 limit 2)
     * union all
     * (select * from product where style=2 limit 3)
     * union all
     * (select * from product where style=3 and id>5 limit 5);
     * 注意：一定查询出来的列必须一致
     * 合并的时候，可以去重（去掉重复）
     * 直接用union
     * -----------------------------------------
     * select * from product ,cuisine ;
     * 如果直接将两个表的数据查询出来，肯定不是我们想要的：笛卡尔积
     * 左边这个表的每一条数据对于右边这个表里面的每一条数据
     * select * from product t1,cuisine  t2
     * where t1.cuisine_id= t2.id;
     * 这就是联合查询，这种联合查询如果表太多，那么看起来就不好看；不好维护
     * 所以推荐用内连接
     * select * from product t1
     * inner join
     * product_cuisine_ralation t3
     * on t1.id=t3.product_id
     * inner join
     * cuisine t2
     * on t2.id=t3.cuisine_id；
     * 注意：
     * 1.正常情况下一个数据库里面用连接的时候，不要超过5张表
     * 2.现在大厂不要超过3个表
     * 3.现在大厂基本上将这些表分别弄在不同的服务器，所以这个在后面做远程调用
     * --------------------------------------------
     * 如果我想把左边的表全部查询出来，右边的表如果和条件不符合，则用null填充即可
     * select * from product t1
     * left join
     * cuisine t2
     * on t2.id=t1.cuisine_id;
     * 这就是左连接：以左边的表为基准，查询出所有数据
     * ---------------------------------------------
     * 右连接和左连接相反
     * select * from product t1
     * right join
     * cuisine t2
     * on t2.id=t1.cuisine_id;
     * -----------
     * select * from cuisine t1
     * left join product t2
     * on t1.id=t2.cuisine_id;
     * 所以左连接和右连接是可以相互转换的：查询数据一样的
     * ----------------------------------------------------------------
     * select -->from-->where -->group by-->having-->order by -->limit
     * 关键字书写顺序
     * having只跟group by相关，如果没有group by则就不需要having
     * having表示对分组过后进行条件语句查询，相当于where条件
     * select price from product group by price having price>150；
     * ----------------------------------------------------------
     * 数据库总结：
     * 1.DDL
     * 2.DML
     * 3.DCL
     * 4.DQL
     * 三大范式和五大约束
     * 查询语句
     * -----------------------------
     * 预习：
     * 1.js https://www.w3school.com.cn/js/index.asp
     * 2.看我以前的登录录屏
     *
     *
     */
    /**
     * 2022-4-13
     * 第四阶段的任务：就是将所有的数据存入数据库，然后通过后台管理系统的模板进行修改
     * 1.将模板下载下来直接引入到项目
     * 2.理清关系：逻辑关系
     * 3.我们要做项目，知道从哪个地方入手
     * ---------------------------------
     * 假如要做登录，那么我们应该怎么办？
     * 1.理清关系：流程图
     * 2.要写哪些页面（前端）
     * 3.要写哪些类（后台）
     * ----------------------------------
     * 流程图：一般在需求文档里面会涉及到，E-R图
     * 对象与对象之间的关系
     * 一对多   1：n
     * 一对一  1：1
     * 多对一  n:1
     * 多对多  m:n
     * -----------------------------------
     * 登录的流程图：
     * 1.任何一个操纵都应该写一个流程图（需求文档里面都应该有所体现）
     * 2.前端应该有哪些文件？
     *      1）登录页面
     *      2）css文件
     *      3）图片文件
     *      4）js文件
     * 3.后台应该有哪些文件？
     *      1）页面控制层   servlet
     *      2）服务逻辑层   service
     *      3）数据持久层   dao
     *      4）实体层       model
     * --------------------------------------
     * 用例图：很直观的展现给用户看之间的关系
     * 会涉及到哪些类呢？
     * 或者他们之间的顺序应该是什么呢？
     * -------------------------------
     * E-R图针对客户，看不懂代码，全是中文
     * 用例图针对开发和测试人员
     * 关联关系：一对一的关系
     * 泛化关系：一对多的关系：父类与子类的关系：登录（微信，账号，手机）
     * 包含关系：一对多的关系：只不过多的表示当前一的细分功能：用户（增加，修改，删除）
     * 拓展关系：一对多的关系：对功能的扩展：登录（登录，忘记密码）
     * 依赖关系：一对一的关系：一个功能依赖另一个功能：登录（用户名，密码），也可以理解为登录和用户对象相关联
     * 第二阶段如果两个类相互依赖，可以理解为一个类作为另一个类的参数进行传递
     * -------------------------------------------------------------
     * E-R图：对象--对象周围是属性
     * 用例图：参与者--用例--周围是方法或行为
     * --------------------------------------
     * 接下来我们应该怎么做？一般如果是一个人来开发的时候，用时间先后顺序
     * 时序图：
     * ---------------------------
     * 接下来需要考虑到底前端和后台要新建哪些文件？
     * 对于前端文件内容写什么？
     * 对于Java后台类的内容写什么？
     * 这里就给大家推荐一个类图：
     * 类图：一般是架构师或者中高级软件工程师来做
     * 里面的具体代码有初级程序员去做
     * ----------------------------------------------------------
     * 今日知识点任务：
     * 1.E-R图复习
     * 2.用例图怎么写？
     * 3.流程图怎么写？
     * 4.时序图怎么写？
     * 5.类图怎么写？
     * 6.将你们的所有对象把类建好；
     * ----------------------------------------
     * 明日安排：
     * 前端逻辑代码：layui.js,jq,ajax,
     *
     */
    /**
     * 2022-4-14
     * 验证码：当我们去查看其他网站的时候，发现验证码其实是一张图片
     * 为什么是图片而不是文字呢？
     * 图片是怎么来的？它保存在哪个地方？
     * ----------------------------------------
     * 为什么需要验证码？验证码的主要作用：
     * 1、防止刷票、论坛灌水、刷页
     * 2、防止黑客恶意破解密码，盗取用户数据
     * 3、防止恶意注册、登录
     * ---------------------------------
     * 如果验证码是字符串，那么我可以通过js植入恶意代码，拿到你的密码
     * 但是如果是图片，则它只能拿到图片，拿不到图片里面的文字
     * -----------------------------------------------
     * 图片验证码的怎么实现的？
     * 1.画一张图片，可以对图片进行背景颜色控制
     * 2.在图片里面写入文字，可以对文字设定不同的样式
     * 3.为了更加安全，可以在文字上面画一些不规则的线条
     * -----------------------------------------------------
     * 图片应该保存在服务器，而不应该保存在浏览器：只要在前端，所有代码都是裸露，不安全
     * 验证码的制作流程
     * 1）画图：画一张白纸图片
     * 2）绘图：将白纸图上颜色（随机）
     * 3）字符：在纸上写字，你可以对字符设置样式
     * 4）干扰：用线条在字上涂鸦，目的让电脑看不懂
     * 5）返回：将图片返回给前端
     * ---------------------------------------------
     * 前端得到验证码：直接调用后台地址：<img src="/code" alt="验证码"/>
     * 我们可以点击图片进行换一张
     * 所以，用到了js的点击事件：onclick="this.src='/code?r='+Math.random()"
     * 如果没有后面的随机数，则每次点击无效，为什么？
     * 是浏览器的保护机制：如果每次都去后台访问，则会消耗计算机性能，
     * 只要访问后台地址一样，则浏览器会默认在缓存里面去取。
     * 所以，在地址后面加了一个随机的参数
     * ---------------------------------------------------------
     * 前端简单的js里面的弹出框和layui的弹出框
     * ---------------------------
     * 今日任务：
     * 1.熟悉验证码的代码
     * 2.熟悉简单的js
     * 3.熟悉js字符串的方法和数组的方法
     * -------------------------------------------
     * 下节课安排：
     * 1.前后台相互传值取值
     * 2.Ajax介绍
     * 3.后台登录的逻辑处理
     */
    /**
     * 2022-4-15
     * 对div添加点击事件
     * 将表单数据提交给后台：
     * 1.这里通过from表达那进行提交（这里不建议）
     * 2.通过ajax传递到后台
     * ${userModel.username}在html里面不能被解释，不能编译
     * 如果要用，则必须用jsp页面
     * ----------------------------------------------------
     * 后台拿到前端的值：
     * String username = req.getParameter("username");
     * 引号里面的username对应的是html里面form表单里面的input里面的name属性
     * 如果想拿到前端传递过来的数组，则
     * String[] hobby=req.getParameterValues("hobby");
     * -----------------------------------------------
     * 由于后台需要传递给前端数据：如果用第二阶段的，那么页面必须是jsp页面
     * 因为这里用的是html所以，不生效，页面拿不到${userModel.username}
     * 所以，我们只能通过ajax来进行前后端数据传输
     * ------------------------------------------------------
     * jq的ajax：是对传统ajax的封装，它的优势在于传输方便，多样化
     * 通过form表单提交，前端不能取得后台的返回的值
     * ----------------------------------------------------------
     * 今日知识点：
     * 1.form表单的提交的两种方式
     * 2.在Java后台这么取得前端的数据
     * 3.在Java后台这么返回给前端
     * 4.在前端这么接收Java返回的数据
     * ------------------------------------------
     * 任务：
     * 1.将前端的数据和后台数据进行打通：
     * 2.试着去写一下登录的service的逻辑代码一致到dao层：（jdbc先不用去管）
     * 3.试着去写一个main函数，手写一个jdbc，连接数据库，能够对数据库数据进行操作
     * 建议：百度
     * --------------------------------------
     * 下节课安排：
     * 1.jdbc
     * 2.将登录逻辑代码完全实现
     * 3.时候会能够跳转到管理页面
     */
    /**
     * 2022-4-18
     * 上节课：通过类图把所有类创建出来
     * 这节课：将各个类里面的代码进行实现：流程图
     * 登录流程图：
     * 1.打开html页面，包括css
     * 2.创建js文件，主要访问后台（ajax）
     * 3.servlet页面控制层
     *      1）得到前端传递给后台的数据
     *      2）将数据封装成对象（只要超过两个以上的参数，而且参数类似，必须封装成对象）
     *          因为我们需要判断验证码或用户名和密码（数据库是否有值）是否正确的结果（应该是属于逻辑判断）
     *      3）需要调用服务逻辑层service
     *      4）得到结果
     *      5）将结果返回给前端
     * 4.service 服务逻辑层代码
     *      思考？
     *      1）首先判断验证码是否正确，错误返回结果结果
     *      2）调用数据层（将用户名和密码传递到数据层，进行数据库查询）
     *      3）根据查询的结果判断用户名或者密码是否在数据库有值
     *      4）有值，返回一个结果
     *      5）没有值，返回一个结果
     * 5.dao  数据实现层里面做事情
     *      1）既然在数据库里面去查询，这里又是数据实现层，所以我们需要得到查询结果
     *          必须要写sql语句
     *      2）需要连接数据库，并得到查询结果集
     *      3）根据结果集分析得到是否有数据
     *      4）直接返回数据
     * 6.jdbc  手写jdbc的步骤
     * ------------------------------------------------------------
     * 为什么会出现ReusltModel？
     * 因为后面所有的操作，我们后台必须给前端一个反馈：
     * 如果反馈的格式很多种，会造成维护的困难
     * 或者前端不容易分清：所以，这里需要和前端进行统一返回数据格式
     * 那么格式应该是什么样子？随便定义
     * 用什么样的模板，就提供什么样的格式
     * 下一节课预习：
     * 1.预习js的相关知识点：String ，Array 里面的方法
     * 2.js的时间格式化
     * 3.sql注入是什么意思？
     *
     */
    /**
     * 2022-4-21
     * 登录成功后进入后台管理页面
     * 1.需要将管理员修改为登录名，怎么在当前页面拿到刚刚登录的用户名
     * 第二阶段如果要在多个页面得到数据：作用域
     * request 只在当前页面
     * session 在这个会话期
     * application  可以跨浏览器，或者删除缓存后也可以拿到
     * 那么对于前端怎么在几个页面拿去数据？
     * 对于前端：session Storage  或者local Storage
     * sessionStorage.setItem("username",data.field.username);
     * js拿到系统时间？Java？
     * 定时器setInterval("getTime()", 1000);
     * 日期格式化：创建一个工具类
     * -----------------------------------------------------------
     * 查询所有的流程
     * 1.页面
     * 2.js
     * 3.servlet  几个固定步骤（今天多一个乱码处理）
     * 4.service 调用数据层，将得到的值放入ReusltModel
     * 5.dao层，调用JDBC得到数据，并解析为集合
     *
     */
    /**
     * 2022-4-25
     * 如果要做用户查询：
     * 1.点击会员列表，弹出会员列表页面
     * 2.页面加载完成执行里面的代码（js代码）
     * 3.将得到的数据进行赋值setData(data)
     * ------------------------------
     * 1.servlet
     *      0.乱码处理 req.setCharacterEncoding("UTF-8");
     *      1.得到前端的数据  String username = req.getParameter("username");
     *      2.分组数据对象  UserModel userModel = new UserModel();
     *      3.调用服务逻辑层  UserService userService = new UserServiceImpl();
     *      4.得到返回的数据（统一数据给是） ResultModel reusltModel = userService.findAll(userModel);
     *      5.将数据返回给前端  resp.getWriter().println(JSONObject.toJSONString(reusltModel));
     * 2.service
     *      1.返回统一格式（前后端达成意见统一）ResultModel reusltModel = new ResultModel();
     *      2.调用数据持久层 UserDao userDao = new UserImpl();
     *      3.得到数据持久层解析后的数据List<UserModel> list = userDao.findAll(userModel);
     *      4.将得到的数据存入reusltModel.setData(list);
     *      5.将resultModel返回
     * 3.dao
     *      1.编写sql语句 String sql = "select * from user";
     *      2.得到查询后的结果集ResultSet resultSet = JDBC.query(sql);
     *      3.对结果集进行解析：while (resultSet.next())
     *      4.将解析后的结果返回给服务逻辑层return list;
     * 4.JDBC 连接数据库，并编译和执行sql语句
     * ------------------------------------------------------
     * 分页做法：
     * 后台主要是sql语句
     * 前端主要是分页模板js语句
     * -----------------------------
     * 1.html   <div id="page"></div>
     * 2.js   layui.use('laypage', function () {
     *                 //得到layui分页对象
     *                 var laypage = layui.laypage;
     *
     *                 //执行一个laypage实例
     *                 laypage.render({
     *                     elem: 'page' //注意，这里的 test1 是 ID，不用加 # 号
     *                     , limit: 20
     *                     , limits: [10, 20, 50]
     *                     , layout: ['count', 'prev', 'page', 'next', 'limit', 'refresh', 'skip']
     *                     , count: res.count //数据总数，从服务端得到
     *                     , jump: function (obj) {
     *                         console.log(obj);
     *                         //分页对象里面必须有第几页和每一页显示多少条
     *                         let data = {page: obj.curr, limit: obj.limit};
     *                         findAll(data);
     *                     }
     *                 });
     *             })
     * 要显示分页：必须先得到总条数
     * --------------------------------------------------------------
     *
     *
     */
    /**
     * 2022-4-27
     * 我们后台需要提供给前端接口：以后项目都是前后端分离
     * 所以，我们应该给前端一个调用的接口地址：对应页面控制层
     * 1.地址是后台给前端的
     * 2.首先提供最基础的接口地址
     * -----------------------------
     * 前端就是提供给用户交互的事情：增删改查
     * 所以，我们首先提供这些基础接口，并把代码写上：让前端尽快进入代码开发
     * 所有查询用get，其他用post
     * 当后台代码写完后，我们需要测试我们的代码功能是否正确，
     * 如果每次都用main方法去做，会写很多代码，很麻烦。
     * 所以，有没有一个专业的测试工具去做这件事情？专业接口测试工具postman
     * 通过浏览器访问，只能访问get方法，不能访问post方法
     * 所以，我们后端应该以最快的速度给前端一个接口地址：
     * 对于增加，修改，删除，数据库返回的数据为影响的条数：如果成功，就影响了一条，失败了就影响了0条
     * -----------------------------------
     * 1.创建servlet层  六大步骤
     * 2.创建service层  封装到ResultModel和调用dao层
     * 3.创建dao层  sql语句编写和解析结果集
     */
    /**
     * 2022-4-28
     * 后端：接收前端的数据，然后将数据和数据库打交道，然后给前端一个反馈
     * 产品的增删改查
     * 1.servlet 六个步骤
     * 删除和根据id查询差不多
     * 增加和修改差不多，只是修改多一个id
     * 查询所有和查询总条数差不多
     * 2.service 服务逻辑层 调用dao层，得到数据，并赋值给ResultModel
     * 3.dao 数据持久层 sql语句编写
     * -------------------------------------------
     * 1.服务逻辑层的BaseService
     * 2.数据持久层的BaseDao
     * 3.泛型
     * --------------------------------
     * servlet层
     *      页面控制层：
     *      六大步骤
     * 页面控制层不能直接调用数据持久层，因为跨界,只能调用服务逻辑层
     * service 服务逻辑层 只能调用dao层，不能调用其他层次
     * dao 查询数据库并将得到的结果解析成service能够看懂的数据
     *
     */

    /**
     * 2022-5-5
     * ResultModel 封装
     * 逻辑层的目的，就是为了和数据层分开
     * 面试？请写一个单例模式?懒汉，饿汉，双检索，枚举，内部类
     * 单例模式：
     * 1.必须是私有的构造方法，
     * 2.必须定义一个私有当前类属性，
     * 3.必须给外面调用一个public的接口
     * -----------------------------------------------------
     * 对于Java后台：servlet的代码
     * 1.servlet  六个步骤   SSM  里面六个步骤就只有一句话
     * 2.service  一个调用方法（逻辑方法除外）
     * 3.dao   sql语句
     * -----------------------------------------------------
     * 动态查询数据列表
     * 1.复制table
     * 2.复制 js ：修改url，修改cols
     * 3.再后台service层加一个，总条数和查询数据的方法
     * 4.如果想打印查询的数据，加 ,parseData: function(res){
     * 明天任务：
     * 状态，操作栏，增加
     */
    /**
     * 2022-5-6
     * 性别，状态，删除
     * -------------------
     * 1.在js里面添加模板 templet: '#sex'
     * 2.在html里面复制模板 <script type="text/html" id="sex">
     * 3.根据当前的性别做出判断哪个显示
     * 4.添加监听事件的js  form.on('switch(sexDemo)',
     * 5.添加ajax，访问后台接口代码
     * ---------------------------------
     * 1变为0，0变为1的四种方式
     * 注意：特别重要信息删除时，需要给用户进行提醒
     */
    /**
     * 2022-5-9 增加
     * 1.复制html代码增加
     * 2.将增加页面的html代码进行修改
     * 第四阶段：可以看懂别人的代码，尽快适应新的项目。
     * java :replace 替换
     * ----------------------------
     * js如果要验证用户格式是否输入正确
     * 1.在html代码里面添加lay-verify="required|username"
     * 2.在js里面添加form.verify({ 里面添加 username:[/[abc]/,"用户名输入不正确"],
     * js里面自定义验证先于提交按钮
     * ---------------------------------------------
     *
     *
     */
    /**
     * 2022-5-10
     * 1.创建html文件
     * 2.添加表单元素
     * 3.点击提交之前：需要对输入的数据进行验证:看懂正则表达式即可
     * 4.点击提交时，拿到所有数据：通过name得到所有数据
     * 5.如果某些表单拿不到值，则需要单独去拿：
     * -------------------------
     * Java后台怎么操作？
     * 1.servlet
     *      1）乱码处理
     *      2）得到前端传递过来的值
     *      3)封装model
     *      4）调用服务逻辑层
     *      5)得到返回的数据（统一格式）
     *      6)将数据返回给前端（IO流）
     * 2.service 服务逻辑层
     *      1）创建一个结果集对象
     *      2）需要对结果集的属性赋值
     *      3）赋值之前，应该调用数据持久层，去执行新增sql语句
     *      4）得到数据持久层返回的影响的条数
     *      5）将结果集返回给servlet
     *      ----------------------------
     *      封装
     * 3.dao
     *      1）编写sql语句
     *      2）如果是新增，修改，删除，直接调用JDBC.update（sql）;
     *      3)如果是查询：JDBC.query(sql);解析结果集
     * 注意：最容易出错的几个地方？
     * 1.sql语句：一定要把sql语句拿到数据库去执行一下，
     * 2.如果sql语句某些值为null，首先去找servlet里面是否有赋值
     * 3.如果已经赋值，还是null，那么就是req.getParameter("birthday");的key值和js对象传递过来的key值没有对应上
     * 4.如果已经对应上，还是null，那么就是js里面的key值本来就是null
     * ---------------------------------------------------------------
     * 5.前端得到后台的数据，直接去做逻辑关系看你会出错res.count == 1会出错，那就表明res没有值，
     *  所以推荐大家在ajax返回前端的第一行将res打印出来，如果正确后就可以删除或者注释
     * 6.如果通过ajax调用后台，没有进入后台断点，什么意思？有几种可能？
     *      1)url可能不正确
     *      2）有咩有可能量ajax的代码都没有执行
     *      3)如果Ajax没有执行，可能前面的代码已经出错
     *      4）如果代码没有出错，就要考虑当前的html是否引入了当前的js文件
     * -------------------------------------------------------------------------
     * 编辑的思路：
     * 1.需要拿到当前编辑的数据的id
     * 2.要根据id去数据库查询，
     * 3.将查询出的数据赋值到编辑页面
     * 4.再修改当前数据，并提交到后台
     * 对应流程图：要学会画流程图
     * -----------------------------------------
     *
     */
    /**
     * 2022-5-11
     * 能在数据库做的不要再Java里面做
     * 能在前端做的不要在Java里面做
     * 以后禁用*代替所有，而是需要什么查询什么
     * --------------------------------------
     * 编辑思路，根据思路一行一行写代码
     * 注意：
     * 1.赋值时，需要重新渲染表单form.render();
     * 2.对复选框赋值：双重for循环
     * 3.单选框赋值：字符串拼接
     * 4.字符串转换为数组
     * 5.y用户无论是新增还是查询密码时，都应该加密，数据库里面不允许出现明文
     */
    /**
     * 2022-5-12  模糊查询
     * 字段，属性:get和set方法去掉set和get 然后第一个字母小写
     * 字段就是指类成员
     * sql语句拼接应该提取到公共方法
     * ---------------------
     * 最主要的就是条件sql语句的拼接
     * 明天的任务：产品新增：
     */
    /**
     * 2022-5-13 产品
     * 1.修改html 的table标签
     * 2.增加layui的js，表格输出
     * ------------------------
     * 需要文件上传：
     * 记住：不要把文件存入数据库，而应该存入文件的地址
     * -------------------------------------------
     * 1.下载jar包2个
     * 2.赋值servlet代码
     * 3.修改文件名称
     * 4.修改保存地址
     * 5.返回json对象，必须是有src的对象
     * 6.将代码提取到工具类
     */
    /**
     * 2022-5-16
     * 富文本
     * 1.赋值html代码 <textarea id="demo" style="display: none;"></textarea>
     * 2.赋值js代码：
     *      1）layui.use(['layedit','upload', 'form', 'layer'],
     *      2）var layedit = layui.layedit;
     *      3） layedit.set({
     *             uploadImage: {
     *                 url: '/upload' //接口url
     *                 ,type: '' //默认post
     *             }
     *         });
     *      4） let index=  layedit.build('demo'); //建立编辑器
     * 3.修改url上传图片的接口地址
     * ---------------------
     * 得到富文本内容：layedit.getContent(index);
     * -----------------------------------------
     * 对富文本赋值： layedit.setContent(index, data.content);
     * 注意：
     * 1.富文本，需要将layedit，和index设置成全局变量
     * 2.如果当前有多个富文本，则需要定义多个layedit和index
     *
     */
    /**
     * 2022-5-17
     * sql注入：不安全
     * 如果不用登录，就可以修改查看后台数据库的数据，不安全，
     * 所以，我们应该让用户先登录，
     * 我们用户每次操作的时候都应该判断是否已经登录
     * ----------------------------------------------
     * 前端正常情况下也应该判断是否已经登录，只需要访问后台的某一个需要验证的地址即可
     * 后台：需要访问后台的地址含有："/back/"以这个开始的都应该进行判断是否已经登录
     * 在用户登录成功以后：需要设定一个标识符
     */
    public static void main(String[] args) {
//        String aa="adbfd\tsfaj\ndks\raj";
//        aa=aa.replace("a","2");
//       int a= aa.indexOf("d");
//        System.out.println(a);
//        System.out.println(aa);
//        ResultModel.getResultModel("aaaa");
//        ResultModel.getResultModel(111);
//        List<String> a = new ArrayList<>();
//        a.add("bbb");
//        ResultModel.getResultModel(a);
//        String a = "abcdefgabcde";
//        System.out.println(a.replace('a', 'u'));
//        List<String> list = new ArrayList<>();
//        List<Object> list1 = new ArrayList<>();
//        try {
//            Method[] methods=Class.forName("com.cn.wanxi.model.UserModel").getMethods();

//            for(Method method:methods){
//
//            }
//            String a="";
//            a.length()
//            字符串是否有length方法，有length属性？数组呢？集合呢？


//        } catch (ClassNotFoundException e) {
//            e.printStackTrace();
//        }

//        String str = "";
//        for (int i = 0; i < 5; i++) {
//
//            System.out.println("这是第" + i + "次循环");
//        }

//        System.out.println(System.currentTimeMillis());
//        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
//        Date date = new Date();
//        String format1 = format.format(date);
//        System.out.println(format1);
//        String age = null;//假如这个数据来源于数据库
//        UserModel userModel = new UserModel();
//        字符串转换为整型
//        userModel.setAge(age);
//        userModel.setName("su");
//        System.out.println(userModel);
    }

}
